package com.ls.atf.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.AndTerm;
import javax.mail.search.FlagTerm;
import javax.mail.search.FromStringTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SubjectTerm;

public class MailHelper {

	private static String receivedFrom = ConfigProperties
			.getAppProperties("autRegistrationEmail");
	private static String login = ConfigProperties
			.getDataProperties("mailbox.email");
	private static String password = ConfigProperties
			.getDataProperties("mailbox.pass");
	private static String host = ConfigProperties
			.getDataProperties("mailbox.imap");
	private static String port = ConfigProperties
			.getDataProperties("mailbox.port");
	private static String subject = ConfigProperties
			.getDataProperties("mailbox.subject");
	private static String receiver = ConfigProperties
			.getDataProperties("manager.displayName");
	private Properties properties;

	public MailHelper() {
		properties = new Properties();
		properties.put("mail.imap.host", host);
		properties.put("mail.imap.port", port);
		properties.setProperty("mail.imap.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		properties.setProperty("mail.imap.socketFactory.fallback", "false");
		properties.setProperty("mail.imap.socketFactory.port", port);
	}

	public boolean hasConfirmationEmail() throws MessagingException,
			IOException {
		boolean res = false;
		Authenticator auth = new MyAuthenticator(login, password);
		Session session = Session.getDefaultInstance(properties, auth);
		Store store = session.getStore("imap");
		store.connect();
		Folder inbox = store.getFolder("INBOX");
		inbox.open(Folder.READ_WRITE);
		Message messages[] = getMessagesFilteredBySenderAndSeen(inbox,
				receivedFrom, subject, true);
		if (messages.length > 0) {
			res = messageContainsReceiver(messages[0], receiver);
		}
		inbox.setFlags(messages, new Flags(Flags.Flag.DELETED), true);
		inbox.close(true);
		store.close();
		return res;
	}

	private Message[] getMessagesFilteredBySenderAndSeen(Folder folder,
			String from, String subject, Boolean seen) {
		Message[] messages = null;
		try {
			SearchTerm filter = new AndTerm(new FromStringTerm(from),
					new SubjectTerm(subject));
			if (!seen) {
				FlagTerm flagSeen = new FlagTerm(new Flags(Flag.SEEN), seen);
				filter = new AndTerm(flagSeen, filter);
			}
			messages = folder.search(filter);
		} catch (MessagingException e) {
			e.printStackTrace();
		}
		return messages;
	}

	private boolean messageContainsReceiver(Message msg, String receiver)
			throws IOException, MessagingException {
		String sBody = null;
		try {
			Multipart multipart = (Multipart) msg.getContent();
			for (int x = 0; x < multipart.getCount(); x++) {
				BodyPart bodyPart = multipart.getBodyPart(x);
				String sMultiBody = getText(bodyPart);
				sBody = sBody + sMultiBody;
			}
		} catch (ClassCastException e) {
			sBody = (String) msg.getContent();
		} finally {
			CharSequence searchPhrase = receiver;
			return sBody.contains(searchPhrase);
		}
	}

	private String getText(Part p) throws MessagingException, IOException {
		if (p.isMimeType("text/*")) {
			String s = (String) p.getContent();
			return s;
		}
		if (p.isMimeType("APPLICATION/OCTET-STREAM")) {
			System.out.println("Mail have some attachment : ");
			DataHandler handler = p.getDataHandler();
			return "file name : " + handler.getName();
		}
		if (p.isMimeType("multipart/alternative")) {
			Multipart mp = (Multipart) p.getContent();
			ArrayList<String> strOut = new ArrayList<String>();
			String text = null;
			for (int i = 0; i < mp.getCount(); i++) {
				Part bp = mp.getBodyPart(i);
				if (bp.isMimeType("text/plain")) {
					if (text == null)
						text = getText(bp);
					strOut.add(text);
				} else if (bp.isMimeType("text/html")) {
					String s = getText(bp);
					if (s != null)
						strOut.add(s);
				} else {
					strOut.add(getText(bp));
				}
			}
			return strOut.toString();
		} else if (p.isMimeType("multipart/*")) {
			Multipart mp = (Multipart) p.getContent();
			for (int i = 0; i < mp.getCount(); i++) {
				String s = getText(mp.getBodyPart(i));
				if (s != null)
					return s;
			}
		}
		return null;
	}

}
